package com.jgit;

import java.io.IOException;
import java.nio.file.Paths;

/**
 * JGit命令行接口
 */
public class JGit {
    
    public static void main(String[] args) {
        if (args.length == 0) {
            printUsage();
            return;
        }
        
        String command = args[0];
        
        try {
            switch (command) {
                case "init":
                    handleInit(args);
                    break;
                case "add":
                    handleAdd(args);
                    break;
                case "commit":
                    handleCommit(args);
                    break;
                case "branch":
                    handleBranch(args);
                    break;
                case "checkout":
                    handleCheckout(args);
                    break;
                case "log":
                    handleLog(args);
                    break;
                case "status":
                    handleStatus(args);
                    break;
                default:
                    System.err.println("Unknown command: " + command);
                    printUsage();
            }
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    private static void printUsage() {
        System.out.println("JGit - A simple Git implementation in Java");
        System.out.println();
        System.out.println("Usage: java com.jgit.JGit <command> [args]");
        System.out.println();
        System.out.println("Commands:");
        System.out.println("  init [path]              Initialize a new repository");
        System.out.println("  add <file>               Add file to staging area");
        System.out.println("  commit -m <message>      Create a new commit");
        System.out.println("  branch [name]            List or create branches");
        System.out.println("  checkout <branch>        Switch to a branch");
        System.out.println("  log                      Show commit history");
        System.out.println("  status                   Show repository status");
    }
    
    private static Repository getRepository() throws IOException {
        String currentDir = System.getProperty("user.dir");
        if (!Repository.isGitRepository(currentDir)) {
            throw new IOException("Not a git repository. Run 'init' first.");
        }
        return new Repository(currentDir);
    }
    
    private static void handleInit(String[] args) throws IOException {
        String path = args.length > 1 ? args[1] : ".";
        Repository repo = Repository.init(path);
        System.out.println("Initialized empty JGit repository in " + 
                          Paths.get(path, ".git").toAbsolutePath());
    }
    
    private static void handleAdd(String[] args) throws IOException {
        if (args.length < 2) {
            System.err.println("Usage: add <file>");
            return;
        }
        
        Repository repo = getRepository();
        repo.add(args[1]);
        System.out.println("Added " + args[1] + " to staging area");
    }
    
    private static void handleCommit(String[] args) throws IOException {
        if (args.length < 3 || !args[1].equals("-m")) {
            System.err.println("Usage: commit -m <message>");
            return;
        }
        
        Repository repo = getRepository();
        String message = args[2];
        String author = System.getProperty("user.name", "Unknown") + 
                       " <" + System.getProperty("user.name", "unknown") + "@localhost>";
        String committer = author;
        
        String commitHash = repo.commit(message, author, committer);
        System.out.println("Created commit " + commitHash.substring(0, 7));
    }
    
    private static void handleBranch(String[] args) throws IOException {
        Repository repo = getRepository();
        
        if (args.length == 1) {
            // 列出所有分支
            String currentBranch = repo.getCurrentBranch();
            for (String branch : repo.getBranches()) {
                if (branch.equals(currentBranch)) {
                    System.out.println("* " + branch);
                } else {
                    System.out.println("  " + branch);
                }
            }
        } else {
            // 创建新分支
            repo.createBranch(args[1]);
            System.out.println("Created branch " + args[1]);
        }
    }
    
    private static void handleCheckout(String[] args) throws IOException {
        if (args.length < 2) {
            System.err.println("Usage: checkout <branch>");
            return;
        }
        
        Repository repo = getRepository();
        repo.checkoutBranch(args[1]);
        System.out.println("Switched to branch " + args[1]);
    }
    
    private static void handleLog(String[] args) throws IOException {
        Repository repo = getRepository();
        String currentHead = repo.getCurrentHead();
        
        if (currentHead == null) {
            System.out.println("No commits yet");
            return;
        }
        
        String commitHash = currentHead;
        int count = 0;
        while (commitHash != null && count < 10) {
            Commit commit = (Commit) repo.getObjectStore().read(commitHash);
            System.out.println("commit " + commitHash);
            System.out.println("Author: " + commit.getAuthor());
            System.out.println("Date:   " + new java.util.Date(commit.getTimestamp() * 1000));
            System.out.println();
            System.out.println("    " + commit.getMessage().replace("\n", "\n    "));
            System.out.println();
            
            if (commit.getParents().isEmpty()) {
                break;
            }
            commitHash = commit.getParents().get(0);
            count++;
        }
    }
    
    private static void handleStatus(String[] args) throws IOException {
        Repository repo = getRepository();
        String currentBranch = repo.getCurrentBranch();
        String currentHead = repo.getCurrentHead();
        
        System.out.println("On branch " + (currentBranch != null ? currentBranch : "detached HEAD"));
        if (currentHead != null) {
            System.out.println("Latest commit: " + currentHead.substring(0, 7));
        }
        
        int stagedFiles = repo.getIndex().getEntries().size();
        if (stagedFiles > 0) {
            System.out.println("\nChanges to be committed:");
            for (Index.IndexEntry entry : repo.getIndex().getEntries().values()) {
                System.out.println("  new file:   " + entry.getPath());
            }
        } else {
            System.out.println("\nNo changes staged for commit");
        }
    }
}

